package strategy;

import windows.MainWindow;

import com.stibocatalog.hunspell.Hunspell;
import com.stibocatalog.hunspell.Hunspell.Dictionary;

public class Affin implements AlgorithmInteface {
	
	private String result;
	private int multKey;
	private int addKey;
	private String text;
	private MainWindow ref;
	private int language;
	
	private char[] abc;
	private Hunspell.Dictionary dictinary;

	public Affin(String text, int multKey, int addKey, int language, MainWindow reference) {
		this.language = language;
		this.text = text;
		this.multKey = multKey;
		this.addKey = addKey;
		ref = reference;
		switch (language) {
		case 0:
			System.out.println("English dictionary loaded!");
			abc = Crypto.ENG_ABC;
			try {
				dictinary = Hunspell.getInstance().getDictionary("Dictionary/en_US");
			} catch (Exception e) {
				e.printStackTrace();
			}
			break;
		case 1:
			System.out.println("Hungarian dictionary loaded!");
			abc = Crypto.HUN_ABC;
			System.out.println(abc);
			try {
				dictinary = Hunspell.getInstance().getDictionary("Dictionary/hu_HU");
			} catch (Exception e) {
				e.printStackTrace();
			}

			break;
		default:
			new Exception("No such language!");
		}
	}
	
	@Override
	public void decrypt() {
		text = text.toLowerCase();
		text = cleanString(text);
		result = "";
		for (int i = 0; i < text.length(); i++) {
			if (getPos(text.charAt(i)) >= 0) {
				int ize2 = (getPos(text.charAt(i)) - addKey);
				if (ize2 < 0) {
					ize2 = abc.length + ize2;
				}
				int ize = ize2 * (abc.length - multKey);
				ize %= abc.length;
				result += abc[ize];
			} 
			else {
				result += text.charAt(i);
			}
		}
		update();
	}
	
	private int getPos(char c) {
		for (int i = 0; i < abc.length; i++) {
			if (abc[i] == c) {
				return i;
			}
		}
		return -1;
	}

	@Override
	public void encrypt() {
		text = text.toLowerCase();
		text = cleanString(text);
		result = "";
		for (int i = 0; i < text.length(); i++) {
			if (getPos(text.charAt(i)) >= 0) {
				int ize = getPos(text.charAt(i)) * multKey + addKey;
				ize %= abc.length;
				result += abc[ize];
			}
			else {
				result += text.charAt(i);
			}
		}
		update();
	}

	public String cleanString(String input){
//		System.out.println(input);
        String cleaned = "";
        char[] in = input.toLowerCase().toCharArray();
        
        for (int i = 0; i < in.length; i++){
            for (char c : abc) {
            	if (in[i] == c){
                    cleaned = cleaned + in[i];
                }
			}
            
            if (in[i] == ' ' || in[i] == '\n'){
                cleaned = cleaned + " ";
            }
        }

        cleaned = cleaned.replaceAll("\\s+", " ");

        return cleaned;
    }
	
	@Override
	public void autoDecrypt() {
		for (int a = 0; a < abc.length; a++) {
			for (int b = 0; b < abc.length; b++) {
				int goodSpell = 0;
				multKey = a;
				addKey = b;
				decrypt();
				
				for (String s : result.split(" ")) {
					if (!dictinary.misspelled(s)) {
						goodSpell++;
					}
				}
				
				if ((((double)goodSpell / result.split(" ").length)) > 0.8) {
					update();
					return;
				}
			}
		}
	}

	@Override
	public void update() {

		ref.affinUpdate(result,multKey,addKey);
	}

}
